package com.fp.m7.performance;

import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;

import org.apache.commons.lang.time.StopWatch;

import com.fp.m7.api.manager.AccountManager;
import com.fp.m7.api.manager.CommentManager;
import com.fp.m7.api.manager.FollowManager;
import com.fp.m7.api.model.Account;
import com.fp.m7.generator.Random;

public class PerformanceTester {

	private static final Logger logger = Logger
			.getLogger(PerformanceTester.class.getName());

	private static final int PAGE = 10;

	private AccountManager accountManager;
	private CommentManager commentManager;
	private FollowManager followManager;

	private Random random;

	public PerformanceTester(AccountManager accountManager,
			CommentManager commentManager, FollowManager followManager,
			Random random) {

		this.accountManager = accountManager;
		this.commentManager = commentManager;
		this.followManager = followManager;
		this.random = random;
	}

	public void performanceTests(List<Serializable> accountIds) {
		int commentListIter = accountIds.size();
		int commentFeedIter = accountIds.size();
		int listFollowersIter = accountIds.size();

		logger.info("Performance tests started");

		StopWatch stopWatch = new StopWatch();
		stopWatch.start();

		StopWatch total = new StopWatch();
		total.start();

		commentList(commentListIter, accountIds);

		logger.info(String.format(
				"Finished testing comment feed iterated %d times in %s.",
				commentListIter, stopWatch));

		stopWatch.reset();
		stopWatch.start();
		commentFeed(commentFeedIter, accountIds);

		logger.info(String.format(
				"Finished testing comment listing iterated %d times in %s.",
				commentFeedIter, stopWatch));

		stopWatch.reset();
		stopWatch.start();
		followers(listFollowersIter, accountIds);

		logger.info(String
				.format("Finished testing listing of followers iterated %d times in %s.",
						listFollowersIter, stopWatch));

		logger.info(String.format(
				"Performance testing process took %s in overall.", total));
	}

	public void commentList(int iterations, List<Serializable> accountIds) {
		for (int i = 0; i < iterations; ++i) {
			Account user = getRandomAccount(accountIds);
			commentManager.findUsersLatestComments(user, PAGE, 0);
		}
	}

	public void commentFeed(int iterations, List<Serializable> accountIds) {
		for (int i = 0; i < iterations; ++i) {
			Account user = getRandomAccount(accountIds);
			commentManager.findCommentFeedForUser(user, PAGE, 0);
		}
	}

	public void followers(int iterations, List<Serializable> accountIds) {
		for (int i = 0; i < iterations; ++i) {
			Account user = getRandomAccount(accountIds);
			followManager.getFollowedByUser(user);
		}
	}

	private Account getRandomAccount(List<Serializable> accountIds) {
		Serializable id = accountIds.get(random.nextInt(accountIds.size()));
		return accountManager.findById(id);
	}
}
